#include "unp.h"

int main(int argc, char** argv) {
	if(argc != 2) {
		err_exit("Usage:%s ip", argv[0]);
	}

	fd_set rfds;

	int fd;
	char buf[MAXLINE];
	struct sockaddr_in serv_addr;

	if((fd = socket(AF_INET,SOCK_STREAM, 0)) == -1) {
		err_exit("socket() error");
	}

	memset(&serv_addr, 0, sizeof(serv_addr));
	serv_addr.sin_family = AF_INET;
	serv_addr.sin_port = htons(9987);
	if(inet_pton(AF_INET,argv[1], &serv_addr.sin_addr) != 1) {
		err_exit("parse ip %s error.", argv[1]);
	}

	if(connect(fd,(struct sockaddr*)&serv_addr, sizeof(serv_addr)) != 0){
		err_exit("connect error");
	}	

	FD_ZERO(&rfds);
	FD_SET(fileno(stdin),&rfds);
	FD_SET(fd,&rfds);

	struct timeval timeout = {0, 10000 };

	for(;;) {
		fd_set nrfds;
		nrfds = rfds;
		int nfds = max(fileno(stdin), fd) + 1;
		int nready = select(nfds, &nrfds, NULL, NULL, &timeout);
		if(nready == 0) continue; // timeout
		if(nready == -1) {
			if(errno == EINTR) continue;
			else {
				err_exit("select error.");
			}
		}
		if(FD_ISSET(fd, &nrfds)) {
			int n = 0;
			if((n = read(fd, buf, MAXLINE)) > 0) {
				buf[n] = 0;
				fputs(buf, stdout);
			} else if(n == 0) {
				printf("peer closed\n"); // 如果是serv端先关闭是不正常的
				break;
			} else if(n == -1) {
				if(errno != EINTR) {
					err_sys("peer reset connection.");
					break;
				}
			}
		}
		if(FD_ISSET(fileno(stdin), &nrfds)) {
			int n = 0;
			if((n = read(fileno(stdin), buf, MAXLINE)) > 0) {
				if(Writen(fd, buf, n) <= 0) {
					err_sys("write data error.");
					close(fd);
					break;
				}
			} else if(n == 0) {
				shutdown(fd, SHUT_WR); // 半关闭
				FD_CLR(fileno(stdin), &rfds);
			}
		}
	}


	close(fd); // 个人习惯，进程退出自动关闭文件描述符

	return 0;
}
